﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using KaartenLib;

namespace WindowsFormsApplication1
{
    public partial class EnenTwintiger : Form
    {
        private KaartSpel kaartSpel = new KaartSpel();

        private Speler speler;
        public Speler Speler {
            set {
                if (speler == null && !(speler is Speler)) {
                    throw new ArgumentException("Speler is verplicht");
                }
                this.speler = value;
            }
            get {
                return speler;
            }
        }

        private List<Kaart> eigenKaarten = new List<Kaart>();
        private List<Kaart> computerKaarten = new List<Kaart>();

        public EnenTwintiger(ref Speler speler)
        {
            this.speler = speler; 
            InitializeComponent();
            kaartSpel.Schudden();
            this.Show();
        }

        private string ZoekKaartBeeld(Kaart kaart)
        {
            try
            {
                StringBuilder image = new StringBuilder();

                switch (kaart.Soort)
                {
                    case KaartSoort.Ruiten:
                        image.Append("di");
                        break;
                    case KaartSoort.Harten:
                        image.Append("he");
                        break;
                    case KaartSoort.Schoppen:
                        image.Append("sp");
                        break;
                    case KaartSoort.Klaveren:
                        image.Append("cl");
                        break;
                }

                switch (kaart.Waarde)
                {
                    case KaartWaarde.Aas:
                        image.Append("1");
                        break;
                    case KaartWaarde.Heer:
                        image.Append("k");
                        break;
                    case KaartWaarde.Dame:
                        image.Append("q");
                        break;
                    case KaartWaarde.Boer:
                        image.Append("j");
                        break;
                    case KaartWaarde.Tien:
                        image.Append("10");
                        break;
                    case KaartWaarde.Negen:
                        image.Append("9");
                        break;
                    case KaartWaarde.Acht:
                        image.Append("8");
                        break;
                    case KaartWaarde.Zeven:
                        image.Append("7");
                        break;
                    case KaartWaarde.Zes:
                        image.Append("6");
                        break;
                    case KaartWaarde.Vijf:
                        image.Append("5");
                        break;
                    case KaartWaarde.Vier:
                        image.Append("4");
                        break;
                    case KaartWaarde.Drie:
                        image.Append("3");
                        break;
                    case KaartWaarde.Twee:
                        image.Append("2");
                        break;
                }
                image.Append(".gif");
                image.Insert(0, @"..\..\KaartAfbeeldingen\");
                return image.ToString();
            }
            catch (Exception)
            {
                MessageBox.Show("Kaartbeeld kan niet geladen worden!!!");
                return null;
            }
        }

        private void DrawCard_Click(object sender, EventArgs e)
        {
            if (eigenKaarten.Count < 7)
            {
                Kaart kaart = kaartSpel.TrekBovensteKaart();
                String url = ZoekKaartBeeld(kaart);
                getrokkenKaartLabel.Text = kaart.ToString();
                PictureBox box = new PictureBox();
                box.Image = new Bitmap(url);
                box.Name = "PictureBoxEigen" + eigenKaarten.Count;
                box.SetBounds(20 + (eigenKaarten.Count * (85)), 20, 75, 95);
                this.Controls.Add(box);
                eigenKaarten.Add(kaart);
                int score = BerekenBestPoint(eigenKaarten);
                if (score >= 21)
                {
                    DrawCard.Enabled = false;
                }
                if (score > 21)
                {
                    OwnPointsLabel.ForeColor = Color.Red;
                    SetRebootButton();
                }
                else if (score == 21) {
                    SetRebootButton();
                }
                OwnPointsLabel.Text = "" + score;
            }
            else if(int.Parse(OwnPointsLabel.Text) <= 21) {
                OwnPointsLabel.ForeColor = Color.Green;
                SetRebootButton();
            }
        }

        private Boolean go = true;

        private void StopButton_Click(object sender, EventArgs e)
        {
            DrawCard.Enabled = false;
            StopButton.Enabled = false;
            go = true;
            while (go)
            {
                ComputerDrawsCard(null, null);
            }
            SetRebootButton();
        }

        public void ComputerDrawsCard (object sender, EventArgs e){
            if (computerKaarten.Count < 7)
            {
                Kaart kaart = kaartSpel.TrekRandomKaart();
                String url = ZoekKaartBeeld(kaart);
                getrokkenKaartLabel.Text = kaart.ToString();
                PictureBox box = new PictureBox();
                box.Image = new Bitmap(url);
                box.Name = "PictureBoxComputer" + computerKaarten.Count;
                box.SetBounds(20 + (computerKaarten.Count * (85)), 135, 75, 95);
                this.Controls.Add(box);
                computerKaarten.Add(kaart);
                int score = BerekenBestPoint(computerKaarten);
                if (score > 21)
                {
                    go = false;
                    ComputerPointsLabel.ForeColor = Color.Red;
                }
                else if (score > int.Parse(OwnPointsLabel.Text))
                {
                    go = false;
                    ComputerPointsLabel.ForeColor = Color.Green;
                }
                ComputerPointsLabel.Text = "" + score;
            }
            else {
                go = false;
            }
        }

        private void SetRebootButton() {
            this.setScore();
            StopButton.Enabled = true;
            StopButton.Click -= new EventHandler(this.StopButton_Click);
            StopButton.Click += new EventHandler(this.Terminate);
            DrawCard.Text = "Herstart";
            DrawCard.Enabled = true;
            DrawCard.Click -= new System.EventHandler(this.DrawCard_Click);
            DrawCard.Click += new System.EventHandler(this.Reboot);
        }

        public void Terminate(object sender, EventArgs args)
        {
            this.Close();
        }

        public void setScore() {
            if (BerekenBestPoint(computerKaarten) > BerekenBestPoint(eigenKaarten))
            {
                //Verloren
                speler.Verlies();
            }
            else { 
                //Gewonnen
                speler.WinstAantalPunten21();
                if (speler.Troef != null && WinstTroefKaart((Kaart)speler.Troef, eigenKaarten)) {
                    speler.WinstAantalPuntenTroef();
                }
                if (speler.ReeksType != null && WinstZelfdeType((KaartSoort)speler.ReeksType, eigenKaarten)){
                    speler.WinstAantalPuntenZelfdeType();
                }
                if(WinstOpeenvolgendeKaarten(eigenKaarten)){
                    speler.WinstAantalPuntenOpeenvolgend();
                }
            }
        }

        private void Reboot(object sender, EventArgs e) {
            this.Hide();
        }

        public static Boolean WinstTroefKaart(Kaart troef, List<Kaart> getrokkenKaarten) {
            foreach (Kaart k in getrokkenKaarten)
            {
                if (k.Equals(troef)) {
                    return true;
                }
            }
            return false;
        }

        public static Boolean WinstZelfdeType(KaartSoort soort, List<Kaart> getrokkenKaarten, int aantalGelijk = 4) {
            int aantal = 0;
            foreach(Kaart k in getrokkenKaarten){
                if ((k.Soort).Equals(soort)) {
                    aantal++;
                }
                if (aantal >= 4) {
                    return true;
                }
            }
            return false;
        }

        public static Boolean WinstOpeenvolgendeKaarten(List<Kaart> getrokkenKaarten) {
            for (int i = 0; i < (getrokkenKaarten.Count - 2); i++) {
                if (((getrokkenKaarten[i].Waarde + 1) == getrokkenKaarten[i + 1].Waarde) && ((getrokkenKaarten[i+1].Waarde + 1) == getrokkenKaarten[i + 2].Waarde))
                {
                    return true;
                }
            }
            return false;
        }

        public static int BerekenBestPoint(List<Kaart> kaarten)
        {
            List<int> scores = new List<int>();
            scores.Add(0);
            foreach (Kaart k in kaarten)
            {
                if (k.isBeeldje() || (k.Waarde == KaartWaarde.Aas))
                {
                    int waarde1 = 1;
                    int waarde2 = 11;
                    if (k.isBeeldje())
                    {
                        waarde1 = ((int)k.Waarde - 10);
                        waarde2 = 10;
                    }
                    List<int> scores2 = new List<int>();
                    for (int i = 0; i < scores.Count; i++)
                    {
                        scores2.Add(scores[i] + waarde1);
                        scores[i] += waarde2;
                    }
                    scores.AddRange(scores2);
                }
                else
                {
                    for (int i = 0; i < scores.Count; i++)
                    {
                        scores[i] += (int)k.Waarde;
                    }
                }
            }
            int score = 0;
            foreach (int s in scores)
            {
                if ((score == 0) || (s > score && s <= 21) || (s < score && s > 21) || (score > 21 && s <= 21))
                {
                    score = s;
                }
            }
            return score;
        }
    }
}
